import json
import logging
import os
import re
import time

import requests
import tornado
from tornado.web import RequestHandler

from base.decoration import maintenance_authenticated
from base.request import BaseHandler
from common.definition import ret_msg, AgencyType
from conf.config import BASE_DIR, FACTORY_UID
from conf.promotion import SHOP_OPENING_PROMO_GOODS_ID
from daemon import tasks
from debug.mqtt_publish import send_mqtt_msg
from helper.coupon_helper import CouponHandler
from helper.mp_helper import fetch_simple_access_token, fetch_simple_jsapi_ticket
from helper.payment.wechat_pay import md5
from helper.user import UserHelper

logger = logging.getLogger("wechat")


class Home(RequestHandler):
    def data_received(self, chunk):
        pass

    @maintenance_authenticated
    def get(self):
        return self.render("home.html")


class NotFoundHandler(BaseHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        context = dict(
            text="404",
        )
        return self.render_html("404.html", **context)


class ErrorHandler(BaseHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        context = dict(
            page_title="消息",
            title="操作失败",
            description="您购买的商品库存不足",
        )
        return self.render_html("error.html", **context)


class SuccessHandler(BaseHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        context = dict(
            page_title="消息",
            title="操作成功",
            description="您购买的商品已经下单",
        )
        return self.render_html("success.html", **context)


class Auth(BaseHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        return self.render_html("auth.html")

    def post(self):
        msg = ""
        ip = self.request.remote_ip
        pwd = self.get_argument("pwd")
        if pwd:
            if pwd == "28806600":
                self.set_secure_cookie(
                    "mid",
                    tornado.escape.json_encode(
                        dict(
                            ip=ip,
                        )
                    ),
                )
                return self.redirect("/")
            else:
                msg = "校验错误，请重新输入"
        context = dict(msg=msg)
        return self.render_html("auth.html", **context)


class MPVerify1(RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        self.set_header("Content-Type", "text/plain")
        return self.write("tPrADLZPLfqpKcKG")


class MPVerify2(RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        self.set_header("Content-Type", "text/plain")
        return self.write("xNu24Ee12jfHJcqH")


class MPVerify3(RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        self.set_header("Content-Type", "text/plain")
        return self.write("dK63Cq21Cd8PcFzm")


class WechatMenu(RequestHandler):
    def data_received(self, chunk):
        pass

    @maintenance_authenticated
    def get(self):
        access_token = fetch_simple_access_token()
        logger.info(access_token)
        with open(os.path.join(BASE_DIR, "static/menu.json"), "r") as f:
            data = f.read()
            logger.info(data)
            r = requests.post(
                url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token="
                + access_token,
                data=data.encode("utf-8"),
            )
            logger.info(r.text)
            return self.write(r.text)


class AccessToken(RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        token = fetch_simple_access_token()
        return self.finish(token)


class JSTicket(RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        ticket = fetch_simple_jsapi_ticket()
        return self.finish(ticket)


class Test(BaseHandler):
    def data_received(self, chunk):
        pass

    # @maintenance_authenticated
    def get(self):
        # open_id = self.get_argument("openid", "o7qyl0sfitoMmBlA0OJH42kd7S1M")
        # self.set_secure_cookie("sid3", tornado.escape.json_encode(dict(
        #     openid=open_id,
        # )))
        # return self.finish(open_id)
        return self.render_html("test.html")

    async def post(self):
        device_id = self.get_argument("device_id")
        message = self.get_argument("message")
        try:
            msg = json.loads(message)
            send_mqtt_msg(device_id, msg)
            return self.finish(ret_msg())
        except Exception as e:
            logger.exception(e)
            return self.finish(ret_msg(-1, error_message=str(e)))


class Mall(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        is_pad = True if re.match(r"^\d+$", open_id) else False

        # 获取用户信息
        code = self.get_argument("code", None)
        state = self.get_argument("state", None)
        if code:
            tasks.user_login.delay(open_id, code)

        if not is_pad:
            # 跳转商城首页
            return self.redirect(f"/static/app1/index.html#/?v={int(time.time())}")
        else:
            # 跳转屏幕商城
            return self.redirect("/static/pad/mall")


class PCMall(BaseHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        return self.redirect("/static/pc/mall/index.html")


class UserAccount(BaseHandler):
    async def get(self):
        open_id = await self.get_open_id()

        # 获取用户信息
        code = self.get_argument("code", None)
        state = self.get_argument("state", None)
        if code:
            tasks.user_login.delay(open_id, code)

        return self.redirect("/static/app1/index.html#/personal")


class Partner(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()

        class Agency(object):
            pass

        class UserAgency(object):
            pass

        session = self.get_db_session(
            [
                {"db_table": "ebt_agency", "model": Agency},
                {"db_table": "ebt_user_agency", "model": UserAgency},
            ]
        )

        ua = session.query(UserAgency).filter_by(ebf_ua_bind_user_id=open_id).first()

        if ua:
            agency = (
                session.query(Agency).filter_by(ebf_agency_id=ua.ebf_agency_id).first()
            )
            if agency:
                agency_id = agency.ebf_agency_id
                agency_type = agency.ebf_agency_type
                agency_sub_type = agency.ebf_agency_sub_type
                if agency_type == AgencyType.STORE:
                    if agency_sub_type == 0:
                        # 线下门店：商家和店员后台
                        return self.redirect("/static/storebackstage/index.html#/index")
                    else:
                        # 线上门店后台
                        return self.redirect("/static/app1/index.html#/workbench")
                elif agency_type == AgencyType.CLERK:
                    parent_agency_id = agency.ebf_agency_parent_id
                    parent_agency = UserHelper.get_agency(parent_agency_id)
                    parent_agency_type = parent_agency.ebf_agency_type
                    parent_agency_sub_type = parent_agency.ebf_agency_sub_type
                    if parent_agency_type == AgencyType.STORE:
                        if parent_agency_sub_type == 0:
                            # 线下门店店员
                            return self.redirect(
                                "/static/storebackstage/index.html#/index"
                            )
                        else:
                            # 线上门店店员
                            return self.redirect("/static/app1/index.html#/workbench")
                    elif parent_agency_type == AgencyType.SUPPLIER:
                        # 供应商职员
                        return self.redirect("/static/admin/index.html#/indexSr")
                    else:
                        logger.error(
                            f"店员账号异常 agency_id={agency_id} parent_agency_type={parent_agency_type}"
                        )
                        # 按普通用户处理
                        return self.redirect("/static/app1/index.html#/personal")
                elif agency_type == AgencyType.SUPPLIER:
                    # 供应商账号
                    return self.redirect("/static/admin/index.html#/indexSr")
                else:
                    # 合伙人后台
                    return self.redirect("/static/app1/index.html#/workbench")
            else:
                # 合伙人记录不存在
                logger.error(f"合伙人记录不存在! open_id={open_id}")
                # 按普通用户处理
                return self.redirect("/static/app1/index.html#/personal")
        # 普通用户
        return self.redirect("/static/app1/index.html#/personal")


class Store(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        is_pad = True if re.match(r"^\d+$", open_id) else False

        if not is_pad:
            # 跳转门店首页
            return self.redirect("/static/store/index.html")
        else:
            # 跳转屏幕商城
            return self.redirect("/static/pad/mall")


class Device(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        return self.redirect("/static/device/index.html")


class AboutUs(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        return self.redirect("https://q.eqxiu.com/s/N9Etz8Vl")


class MyWine(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        return self.redirect("/static/app/index.html#/myWine")


class InvitePartner(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        return self.redirect("/static/register/index.html#/invitePartner1Qr")


# 合伙人注册中转
class Register(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self, type, inviter):
        await self.get_open_id()
        type = int(type)
        if type == 3:
            url = f"/static/register/index.html#/register/{type}/{inviter}"
        elif type == 5:
            url = f"/static/register/index.html#/referrerRegister/{type}/{inviter}"
        elif type == 53:
            url = "/static/register/index.html#/cooperMerchant"
        elif type == 31:
            url = f"/static/register/index.html#/expertRegister/2/{inviter}"
        elif type == 32:
            url = f"/static/register/index.html#/expertRegister/2/{inviter}"
        elif type == 33:
            url = f"/static/register/index.html#/careerRegister/3/{inviter}"
        return self.redirect(url)


class TemplateMesage(BaseHandler):
    """模板消息目标页面中转"""

    def data_received(self, chunk):
        pass

    async def get(self):
        await self.get_open_id()
        title = self.get_argument("title", None)
        if title == "number_remind":
            # 跳转到门店选择页
            url = "/static/store/index.html#/choose"
        elif title == "tiyan":
            # 跳转到9.9体验商品介绍页
            url = "/static/app/index.html#/about9-9"
        elif title == "99":
            # 跳转到99元新人礼包介绍页
            # url = "/static/app/index.html#/about-99"
            url = "/static/app1/index.html#/newGift"
        elif title == "108":
            # 跳转到108元新人礼商品详情页
            url = "/static/app1/index.html#/productDetails?goods_id=573631115863884"
        elif title == "coupon":
            # 跳转到L款详情页
            url = (
                "/static/app/index.html#/productDetails?goods_id=523948811961181&type=1"
            )
        elif title == "gift_application":
            # 跳转到领取礼品页
            url = "/static/app1/index.html#/giftIntroduction"
        elif re.match(r"^\d+$", title):
            # 跳转到发现文章详情页
            url = f"/static/discover/index.html#/comment-detail?id={title}"
        else:
            # 默认跳转到商城
            url = "/static/app1/index.html#/mall"
        return self.redirect(url)


class UserPoster(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()

        # 获取用户信息
        code = self.get_argument("code", None)
        state = self.get_argument("state", None)
        if code:
            tasks.user_login.delay(open_id, code)

        if self.is_partner(open_id):
            return self.redirect("/static/app1/index.html#/selectPoster")
        return self.redirect("/static/app1/index.html#/poster")


class WineCard(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        return self.redirect("/static/winecard/index.html#/cardQrCode")


class Promotion(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        return self.redirect("/static/app1/index.html#/getShopOpenCoupon")

    async def post(self):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        coupon_id = 11  # 新店酬宾礼券
        if not CouponHandler.create_coupon(open_id, coupon_id):
            logger.error(f"wx/promotion: 领券失败")
        return self.redirect(f"/goods/{SHOP_OPENING_PROMO_GOODS_ID}")


class PromotionPoster(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        return self.redirect("/static/app1/index.html#/shopOpen")


class CouponBuy(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        coupon_id = 11  # 新店酬宾礼券
        if not CouponHandler.create_coupon(open_id, coupon_id):
            logger.error(f"wx/promotion: 领券失败")
        return self.redirect(f"/goods/{SHOP_OPENING_PROMO_GOODS_ID}")


class Discover(BaseHandler):
    def data_received(self, chunk):
        pass

    async def get(self):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        return self.redirect("/static/app1/index.html#/main-page")


class QR(BaseHandler):
    """
    可变二维码
    
    """
    def data_received(self, chunk):
        pass

    async def get(self, qr_id):
        logger.info(f"qr: {qr_id}")

        class QRLink(object):
            pass

        session = self.get_db_session([{"db_table": "ebt_qrlink", "model": QRLink}])

        qr = session.query(QRLink).filter_by(id=qr_id).first()
        if qr:
            url = qr.url
            if url:
                return self.redirect(url)
            else:
                return self.redirect("/404")
        else:
            return self.redirect("/404")


class GiftQR(BaseHandler):
    """
    礼品订购可变二维码

    """
    def data_received(self, chunk):
        pass

    async def get(self, card_id, code):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        logger.info(f"GiftCard: id={card_id} code={code} open_id={open_id}")

        # 校验礼品卡
        code_str = FACTORY_UID + card_id
        sign = md5(code_str.encode()).upper()
        if code != sign:
            logger.error(f"礼品卡: {card_id} 验证码 {code} 无效!")
            # 无效卡跳转链接
            return self.redirect(
                f"/static/giftcard/index.html#/invalid?id={card_id}&code={code}"
            )

        class GiftCard(object):
            pass

        session = self.get_db_session(
            [{"db_table": "ebt_gift_card", "model": GiftCard}]
        )

        qr = session.query(GiftCard).filter_by(id=card_id).first()
        # 待激活礼品卡跳转链接
        url0 = f"/static/giftcard/index.html#/activate?id={card_id}&code={code}"
        # 待领取礼品卡跳转链接
        url1 = f"/static/giftcard/index.html#/getGift?id={card_id}&code={code}"
        # 已领取礼品卡跳转链接
        url2 = f"/static/giftcard/index.html#/nonvalid?id={card_id}&code={code}"
        if qr:
            status = qr.status
            if status == 0:
                return self.redirect(url0)
            elif status == 1:
                return self.redirect(url1)
            elif status == 2:
                return self.redirect(url2)
            else:
                logger.error(f"礼品卡: {card_id} 未知状态码: {status}")
                return self.redirect("/404")
        else:
            logger.error(f"礼品卡: {card_id} 不存在!")
            return self.redirect("/404")


class VipQR(BaseHandler):
    """
    员工可变二维码

    """
    async def get(self, vip_id, code):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        logger.info(f"VipCard: id={vip_id} code={code} open_id={open_id}")

        # 待激活员工卡跳转链接
        url0 = f"/static/giftcard/index.html#/activateVip?id={vip_id}&code={code}"
        # 已激活员工卡跳转链接为vip商城
        url1 = f"/static/mall-2x/index.html#/mall?vip={vip_id}&code={code}"
        # 无效员工卡跳转链接
        url2 = f"/static/giftcard/index.html#/nonvalidVip?id={vip_id}&code={code}"
        # 扫码人与持卡人不一致跳转链接
        url3 = f"/static/giftcard/index.html#/differentVip?id={vip_id}&code={code}"

        class VipCard(object):
            pass

        session = self.get_db_session([{"db_table": "ebt_vip_card", "model": VipCard}])
        qr = session.query(VipCard).filter_by(id=vip_id).first()

        if qr:
            status = qr.status
            oid = qr.open_id
            sign = qr.code
            if code != sign:
                logger.error(f"员工卡: {vip_id} 验证码 {code} 无效!")
                session.close()
                return self.redirect(url2)

            if status == 0:
                session.close()
                return self.redirect(url0)
            elif status == 1:
                if oid != open_id:
                    logger.info(
                        f"扫码人与持卡人不一致:oid={oid} open_id={open_id} vip_id={vip_id}"
                    )
                    session.close()
                    return self.redirect(url3)
                session.close()
                return self.redirect(url1)
            elif status == 2:
                session.close()
                return self.redirect(url2)
            else:
                logger.error(f"员工卡: {vip_id} 未知状态码: {status}")
                session.close()
                return self.redirect("/404")
        else:
            logger.error(f"员工卡: {vip_id} 不存在!")
            session.close()
            return self.redirect("/404")


class Vip(BaseHandler):
    """
    电子贵宾卡中转页

    """
    async def get(self, vip_id, code):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        return self.redirect(f"/static/app1/index.html#/VIP?id={vip_id}&code={code}")


class Goods(BaseHandler):
    """
    商品导购中转页

    https://wx.laez9.com/goods/599103763461525?jstarcode=119
    https://wx.laez9.com/goods/599103763461525?id=1
    https://wx.laez9.com/goods/599103763461525?Id=1

    """
    async def get(self, goods_id):
        open_id = await self.get_open_id()
        await self.bind_user(open_id)
        return self.redirect(
            f"/static/app1/index.html#/productDetails?goods_id={goods_id}"
        )


class Order(BaseHandler):
    """
    订单详情中转页

    https://wx.laez9.com/order/16215770931176330

    """
    async def get(self, order_id):
        open_id = await self.get_open_id()
        return self.redirect(f"/static/app1/index.html#/orderDetails/{order_id}")
